// switch.c
// 用于管理开关
#include "freertos/FreeRTOS.h"  // xTaskCreate
#include "driver/gpio.h"  // gpio_config
#include "esp_timer.h"  // esp_timer_get_time
#include "esp_err.h"  // ESP_ERROR_CHECK
#include "esp_log.h" // ESP_LOGI
#include "common.h"

// 暴露变量
TaskHandle_t switch_handle = NULL;
volatile uint32_t switch_state = 0;
// 内部变量
static volatile int64_t last_isr_time = 0;
static const char *TAG = "SWITCH";
// 中断任务
static void IRAM_ATTR switch_isr(void *arg) {
  int64_t current_time = esp_timer_get_time();  // 自初始化后微秒数 休眠唤醒后重置
  if (current_time-last_isr_time > 200*1000 ) {  // 200ms防抖
    xTaskNotifyFromISR(switch_handle, 0, eNoAction, NULL);
    last_isr_time = current_time;
  }
}

void switch_task(void *arg) {
  /*--------初始化--------*/
  gpio_config_t io_config = {  // 配置GPIO
    .mode = GPIO_MODE_INPUT,
    .pull_up_en = GPIO_PULLUP_ENABLE,
    .pull_down_en = GPIO_PULLDOWN_DISABLE,
    .intr_type = GPIO_INTR_NEGEDGE,  // 下降沿触发
    .pin_bit_mask = (1ULL << BUTTON_PIN),
  };
  ESP_ERROR_CHECK(gpio_config(&io_config));
  ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_IRAM));  // 中断在内存
  switch_state = 0;  // 默认关
  ESP_LOGI(TAG, "init finish.");
  /*--------开关逻辑--------*/
  while (true) {
    /*--------处理开关--------*/
    ESP_LOGI(TAG, "----------------------------------------------------------");
    ESP_ERROR_CHECK(gpio_isr_handler_add(BUTTON_PIN, switch_isr, NULL));
    xTaskNotifyStateClear(switch_handle);
    xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
    ESP_ERROR_CHECK(gpio_isr_handler_remove(BUTTON_PIN));
    switch_state = switch_state == 0 ? 1 : 0;  // 切换状态
    ESP_LOGI(TAG, "state: %s.", switch_state == 1 ? "on" : "off");
    // /*--------led任务--------*/
    // ESP_LOGI(TAG, "notify led task.");
    // xTaskNotifyStateClear(switch_handle);
    // xTaskNotify(led_handle, 0, eNoAction);
    // xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
    // ESP_LOGI(TAG, "led task finish.");
    // /*--------http任务--------*/
    // ESP_LOGI(TAG, "notify http task.");
    // xTaskNotifyStateClear(switch_handle);
    // xTaskNotify(http_handle, 0, eNoAction);
    // xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
    // ESP_LOGI(TAG, "http task finish.");
    // /*--------wifi任务--------*/
    // ESP_LOGI(TAG, "notify wifi task.");
    // xTaskNotifyStateClear(switch_handle);
    // xTaskNotify(wifi_handle, 0, eNoAction);
    // xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
    // ESP_LOGI(TAG, "wifi task finish.");
    /*--------host任务--------*/
    ESP_LOGI(TAG, "notify host task.");
    xTaskNotifyStateClear(switch_handle);
    xTaskNotify(host_handle, 0, eNoAction);
    xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
    ESP_LOGI(TAG, "host task finish.");
  }
}
